home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / test / mandelbrot.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-13  |  5.1 KB  |  202 lines

  1. //
  2. // "$Id: mandelbrot.cxx,v 1.8 1999/01/13 15:45:50 mike Exp $"
  3. //
  4. // Mandelbrot set demo for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. #include "mandelbrot_ui.cxx"
  27. #include <FL/fl_draw.H>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30.  
  31. Drawing_Window mbrot;
  32. Drawing_Window jbrot;
  33.  
  34. void idle() {
  35.   if (!mbrot.d->idle() && !(jbrot.d && jbrot.d->idle())) Fl::set_idle(0);
  36. }
  37.  
  38. void set_idle() {
  39.   Fl::set_idle(idle);
  40. }
  41.  
  42. static void window_callback(Fl_Widget*, void*) {exit(0);}
  43.  
  44. int main(int argc, char **argv) {
  45.   mbrot.make_window();
  46.   mbrot.d->X = -.75;
  47.   mbrot.d->scale = 2.5;
  48.   mbrot.update_label();
  49.   int i = 0;
  50.   if (Fl::args(argc,argv,i) < argc) Fl::fatal(Fl::help);
  51.   Fl::visual(FL_RGB);
  52.   mbrot.window->callback(window_callback);
  53.   mbrot.window->show(argc,argv);
  54.   Fl::run();
  55.   return 0;
  56. }
  57.  
  58. void Drawing_Window::update_label() {
  59.   char buffer[128];
  60.   sprintf(buffer, "%+.10f", d->X); x_input->value(buffer);
  61.   sprintf(buffer, "%+.10f", d->Y); y_input->value(buffer);
  62.   sprintf(buffer, "%.2g", d->scale); w_input->value(buffer);
  63. }
  64.  
  65. void Drawing_Area::draw() {
  66.   draw_box();
  67.   drawn = 0;
  68.   set_idle();
  69. }
  70.  
  71. int Drawing_Area::idle() {
  72.   if (!window()->visible()) return 0;
  73.   if (drawn < nextline) {
  74.     window()->make_current();
  75.     int yy = drawn+y()+4;
  76.     if (yy >= sy && yy <= sy+sh) erase_box();
  77.     fl_draw_image_mono(buffer+drawn*W,x()+3,yy,W,1,1,W);
  78.     drawn++;
  79.     return 1;
  80.   }
  81.   if (nextline < H) {
  82.     if (!buffer) buffer = new uchar[W*H];
  83.     double yy = Y+(H/2-nextline)*scale/W;
  84.     double yi = yy; if (julia) yy = jY;
  85.     uchar *p = buffer+nextline*W;
  86.     for (int xi = 0; xi < W; xi++) {
  87.       double xx = X+(xi-W/2)*scale/W;
  88.       double wx = xx; double wy = yi;
  89.       if (julia) xx = jX;
  90.       for (int i=0; ; i++) {
  91.     if (i >= iterations) {*p = 0; break;}
  92.     double t = wx*wx - wy*wy + xx;
  93.     wy = 2*wx*wy + yy;
  94.     wx = t;
  95.     if (wx*wx + wy*wy > 4) {
  96.       wx = t = 1-double(i)/(1<<10);
  97.       if (t <= 0) t = 0; else for (i=brightness; i--;) t*=wx;
  98.       *p = 255-int(254*t);
  99.       break;
  100.     }
  101.       }
  102.       p++;
  103.     }
  104.     nextline++;
  105.     return nextline < H;
  106.   }
  107.   return 0;
  108. }
  109.  
  110. void Drawing_Area::erase_box() {
  111.   window()->make_current();
  112.   fl_overlay_clear();
  113. }
  114.  
  115. int Drawing_Area::handle(int event) {
  116.   static int ix, iy;
  117.   static int dragged;
  118.   static int button;
  119.   int x2,y2;
  120.   switch (event) {
  121.   case FL_PUSH:
  122.     erase_box();
  123.     ix = Fl::event_x(); if (ix<x()) ix=x(); if (ix>=x()+w()) ix=x()+w()-1;
  124.     iy = Fl::event_y(); if (iy<y()) iy=y(); if (iy>=y()+h()) iy=y()+h()-1;
  125.     dragged = 0;
  126.     button = Fl::event_button();
  127.     return 1;
  128.   case FL_DRAG:
  129.     dragged = 1;
  130.     erase_box();
  131.     x2 = Fl::event_x(); if (x2<x()) x2=x(); if (x2>=x()+w()) x2=x()+w()-1;
  132.     y2 = Fl::event_y(); if (y2<y()) y2=y(); if (y2>=y()+h()) y2=y()+h()-1;
  133.     if (button != 1) {ix = x2; iy = y2; return 1;}
  134.     if (ix < x2) {sx = ix; sw = x2-ix;} else {sx = x2; sw = ix-x2;}
  135.     if (iy < y2) {sy = iy; sh = y2-iy;} else {sy = y2; sh = iy-y2;}
  136.     window()->make_current();
  137.     fl_overlay_rect(sx,sy,sw,sh);
  138.     return 1;
  139.   case FL_RELEASE:
  140.     if (button == 1) {
  141.       erase_box();
  142.       if (dragged && sw > 3 && sh > 3) {
  143.     X = X + (sx+sw/2-x()-W/2)*scale/W;
  144.     Y = Y + (-sy-sh/2+y()+H/2)*scale/W;
  145.     scale = sw*scale/W;
  146.       } else if (!dragged) {
  147.     scale = 2*scale;
  148.     if (julia) {
  149.       if (scale >= 4) {
  150.         scale = 4;
  151.         X = Y = 0;
  152.       }
  153.     } else {
  154.       if (scale >= 2.5) {
  155.         scale = 2.5;
  156.         X = -.75;
  157.         Y = 0;
  158.       }
  159.     }
  160.       } else return 1;
  161.       ((Drawing_Window*)(user_data()))->update_label();
  162.       new_display();
  163.     } else if (!julia) {
  164.       if (!jbrot.d) {
  165.     jbrot.make_window();
  166.     jbrot.d->julia = 1;
  167.     jbrot.d->X = 0;
  168.     jbrot.d->Y = 0;
  169.     jbrot.d->scale = 4;
  170.     jbrot.update_label();
  171.       }
  172.       jbrot.d->jX = X + (ix-x()-W/2)*scale/W;
  173.       jbrot.d->jY = Y + (H/2-iy+y())*scale/W;
  174.       static char buffer[128];
  175.       sprintf(buffer, "Julia %.7f %.7f",jbrot.d->jX,jbrot.d->jY);
  176.       jbrot.window->label(buffer);
  177.       jbrot.window->show();
  178.       jbrot.d->new_display();
  179.     }
  180.     return 1;
  181.   }
  182.   return 0;
  183. }
  184.  
  185. void Drawing_Area::new_display() {
  186.   drawn = nextline = 0;
  187.   set_idle();
  188. }
  189.  
  190. void Drawing_Area::resize(int X,int Y,int W,int H) {
  191.   if (W != w() || H != h()) {
  192.     this->W = W-6;
  193.     this->H = H-8;
  194.     if (buffer) {delete[] buffer; buffer = 0; new_display();}
  195.   }
  196.   Fl_Box::resize(X,Y,W,H);
  197. }
  198.  
  199. //
  200. // End of "$Id: mandelbrot.cxx,v 1.8 1999/01/13 15:45:50 mike Exp $".
  201. //
  202.